package com.ddx.common.util;


import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by dudianbo on 16-7-11.
 * 日期工具类
 */
public class DateUtil extends DateUtils {


    private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class);
    public static final String YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String YYYYMMDD_000000 = "yyyy-MM-dd 00:00:00";
    public static final String YYYYMMDD_235959 = "yyyy-MM-dd 23:59:59";
    public static final String yyyyMMddHHmmss = "yyyyMMddHHmmss";
    public static final int SECONDS_OF_ONE_DAY = 24 * 60 * 60;

    public static Date getNowDate() {
        return Calendar.getInstance().getTime();
    }

    public static int getNowDayOfWeek() {
        int index = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
        return index == 1 ? 7 : index - 1;
    }

    public static int getNowDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK) == 1 ? 7 : calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    public static Timestamp getNowTime() {
        return new Timestamp(getNowDate().getTime());
    }


    public static Timestamp getNowTime(long time) {
        return new Timestamp(time);
    }

    public static Date getDateByTime(long time) {
        return new Date(time*1000L);
    }
    public static Date getAfterHoursDate(Date currentDate, int hours) throws ParseException {
        Date returnDate = null;
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        c.add(Calendar.HOUR, hours);
        Date d = c.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD_HHMMSS);

        returnDate = sdf.parse(sdf.format(d));

        return returnDate;
    }

    /**
     * 获取一个时间范围内的所有日期
     *
     * @param beginDate 开始日期
     * @param endDate   结束日期
     * @return
     */
    public static List<Date> getDates(Date beginDate, Date endDate) {
        beginDate = formatToDate(beginDate, YYYYMMDD);
        endDate = formatToDate(endDate, YYYYMMDD);
        List<Date> dates = new ArrayList<Date>();
        if (endDate.compareTo(beginDate) > 0) {
            Date index = formatToDate(beginDate, YYYYMMDD);
            while (index.compareTo(endDate) <= 0) {
                dates.add(index);
                index = getTomorrow(index);
            }
        } else if (endDate.compareTo(beginDate) == 0) {
            dates.add(formatToDate(beginDate, YYYYMMDD));
        }
        return dates;
    }


    /**
     * 获取输入日期的前一个月
     *
     * @param currentDate 输入日期
     * @return 输入日期的前一个月的日期
     */
    public static Date getDateBeforeMonth(Date currentDate) {
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        c.add(Calendar.MONTH, -1);
        Date d = c.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD);
        return createDate(sdf.format(d), YYYYMMDD);
    }

    /**
     * 获取输入日期的前一天
     *
     * @param currentDate 输入日期
     * @return 输入日期的前一天
     */
    public static Date getYesterday(Date currentDate) {
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        c.add(Calendar.DATE, -1);
        Date d = c.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD);
        return createDate(sdf.format(d), YYYYMMDD);
    }

    /**
     * 获取输入日期的后一天
     *
     * @param currentDate 输入日期
     * @return 输入日期的前一天
     */
    public static Date getTomorrow(Date currentDate) {
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        c.add(Calendar.DATE, 1);
        Date d = c.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD);
        return createDate(sdf.format(d), YYYYMMDD);
    }

    /**
     * 获取输入日期的当月第一天
     *
     * @param currentDate 输入日期
     * @return 输入日期的当月第一天
     */
    public static Date getFirstDayOfMonth(Date currentDate) {
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        c.set(Calendar.DATE, 1);
        Date d = c.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD);
        return createDate(sdf.format(d), YYYYMMDD);
    }
    /**
     * 获取当前月份最后一天
     *
     * @param currentDate
     * @return
     * @throws ParseException
     */
    public static Date getMaxMonthDate(Date currentDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date d = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD);
        return createDate(sdf.format(d), YYYYMMDD);
    }
    /**
     * 将时间格式的字符串，转化为Date
     *
     * @param dateFormat exp: 2010-7-22
     * @return java.util.Date
     */
    public static Date createDate(String dateString, String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        Date d = null;
        try {
            d = sdf.parse(dateString);
        } catch (ParseException e) {
            LOGGER.error("字符串转化为Date失败,[string=" + dateString + "]", e);
        }
        return d;
    }

    /**
     * 将时间转化为指定格式的字符串
     *
     * @param date   输入日期
     * @param format 日期格式
     * @return 字符串格式的日期
     * @author lishuai
     */
    public static String format(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    public static String formatAddTime(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date) + " 23:59:59";
    }

    public static String format2AddLastTime(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD_235959);
        return sdf.format(parseDate(date, YYYYMMDD));
    }

    public static String format2AddFirstTime(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD_000000);
        return sdf.format(parseDate(date, YYYYMMDD));
    }

    public static Timestamp format2AddLastTime(Timestamp date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD_235959);
        return new Timestamp(parseDate(sdf.format(date), YYYYMMDD_HHMMSS).getTime());
    }

    public static Timestamp format2AddFirstTime(Timestamp date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD_000000);
        return new Timestamp(parseDate(sdf.format(date), YYYYMMDD_HHMMSS).getTime());
    }

    public static Date parseDate(String str, String... parsePatterns) throws ParseException {

        return DateUtils.parseDate(str, parsePatterns);

    }
    public static Date formatToDate(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return createDate(sdf.format(date), format);
    }

    /**
     * 根据给予的时间获取当前一天的最早时间
     *
     * @param cdate
     * @return
     */
    public static Integer getStartDate(Integer cdate) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(cdate * 1000L);
        // 将时间设置为当天的0点0分0秒
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return (int) (cal.getTimeInMillis() / 1000);
    }
    public static Date getStartTimeOfDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 将时间设置为当天的0点0分0秒
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND,0);
        return cal.getTime();
    }

    /**
     * 根据给予的时间获取当前一天的最后时间
     *
     * @param cdate
     * @return
     */
    public static Integer getEndDate(Integer cdate) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(cdate * 1000L);
        // 将时间设置为当天的23点59分59秒
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);

        return (int) (cal.getTimeInMillis() / 1000);
    }

    /**
     * 获取以毫秒为单位的当前时间。保留10位
     *
     * @return
     */
    public static int getCurrentTime() {
        return (int) (System.currentTimeMillis() / 1000);
    }

    /**
     * 获取以毫秒为单位的当前时间。保留10位
     *
     * @return
     */
    public static int getYestdayTime() {
        return (int) (System.currentTimeMillis() / 1000) - SECONDS_OF_ONE_DAY;
    }

    /**
     * 获取当天的年月日
     * @return
     */
    public static String getCurrentYMD(){
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        return sf.format(date);
    }

    /**
     * 将日期格式转换为时间戳格式
     * @return
     */
    public static String rversalTime(String dateString, String dateFormat){
        Date date=createDate(dateString,dateFormat);
        return String.valueOf(Long.valueOf(date.getTime()/1000));
    }
    /**
     * 获取指定时间戳
     * @return
     */
    public static Long rversalTime(String dateString){
        Long timestamp = Long.valueOf(System.currentTimeMillis() / 1000);
        return timestamp - (Long.valueOf(dateString)*60L);
    }
    /**
     * @Description: N月之后
     * @param @param n
     * @param @param date
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     */
    public static Date nMonthAfter(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + n);
        return cal.getTime();
    }
    /**
     * @Description: N日之后
     * @param @param n
     * @param @param date
     * @param @return 设定文件
     * @return Date 返回类型
     * @throws
     */
    public static Date nDayAfter(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + n);
        return cal.getTime();
    }

    /**
     * 计算两个日期之间的天数 进方法之前要保证参数不为null
     * @param beginDate 开始日期
     * @param endDate  结束日期
     * @return
     */
    public static int betweenDayNumber(Date beginDate, Date endDate) {
        Long days=(endDate.getTime()-beginDate.getTime())/(1000*3600*24);
        return days.intValue()+2;
    }
    /**
     * 计算两个日期之间的天数 进方法之前要保证参数不为null
     * @param beginDate 开始日期
     * @param endDate  结束日期
     * @return
     */
    public static int betweenInvestDayNumber(Date beginDate, Date endDate) {
        List<Date> list=getDates(beginDate,endDate);
        return list.size();
    }
    /**
     * 按指定规则进行日期比较，只要格式化后的字符串相等则认为日期相等
     *
     * @param one
     * @param two
     * @param format 指定日期格式，
     * @return
     */
    public static boolean equals(Date one, Date two, String format) {
        if (one == null && two == null) {
            return true;
        }
        if (one != null && two != null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);

            if (simpleDateFormat.format(one).equals(simpleDateFormat.format(two))) {
                return true;
            }
        }
        return false;
    }
    /**
     * 根据投资产品生产结束时间  当日计息 加日期减一
     *
     * @param productTermType '产品期限类型 1:天、2:月、3:年',
     * @param productTerm '产品期限(活期产品不考虑期限)',
     * @return
     */
    public static Date createEndDateByProduct(Integer productTermType, Integer productTerm) {
        Calendar calendar=Calendar.getInstance();
        if(productTermType==1){
            calendar.add(Calendar.DATE,+(productTerm-1));
        }else if(productTermType==2){
            calendar.add(Calendar.DATE,-1);
            calendar.add(Calendar.MONTH,+productTerm);
        }else if(productTermType==3){
            calendar.add(Calendar.DATE,-1);
            calendar.add(Calendar.YEAR,+productTerm);
        }
        return calendar.getTime();
    }

    public static Integer calculateDays(Integer productTermType, Integer productTerm){
        if(productTermType==2){
           return 30*productTerm;
        }else if(productTermType==3){
            return 365* productTerm;
        }
        return productTerm;
    }
    public static String converDate(Date startDate){
        Long l=System.currentTimeMillis()-startDate.getTime();
        String s="一分钟内";
        //计算天数
        int day=(int) ((l)/86400000);
        if(day>0){
            s=day+"天前";
            return s;
        }
        //计算小时
        int h=(int) (((l)%86400000)/3600000);
        if(h>0){
            s=h+"小时前";
            return s;
        }
        //计算分钟
        int m=(int)(((l)%86400000)%3600000)/60000;
        if(m>0){
            s=m+"分钟前";
            return s;
        }
        return s;
    }

    public static void main(String[] args) {
        System.out.println(createEndDateByProduct(2,3));
    }
}
